<template>
  <div class="chat-container">
    <audio id="audioAi" ref="audioAi" @ended="ONRec" controls hidden="true"></audio>
    <audio id="audio" @ended="cleanRec" ref="audio" controls hidden="true"></audio>
    <div class="chat-container-content" :style="getBackgroundStyle(chatRoombgk)">
      <!-- 数字人显示区域 -->

      <div class="ai-avatar">
        <!-- <img crossorigin="anonymous" class="backImg" :src="aiimg" v-if="imgElement" alt="" /> -->
        <div class="ai-avatar-box">
          <!-- <img crossorigin="anonymous" class="backImg" :src="imgElement" v-if="imgElement != ''" alt="" /> -->
          <img crossorigin="anonymous" class="backImg" :src="imgElement" v-if="imgElement != ''" alt="" />

        </div>

        <!-- <video autoplay id="mybackVideo" :src="videoBgSrc" crossorigin="anonymous"
                        style="width: 100%; height: 100%" poster></video> -->
        <div v-html="videoBgSrc"></div>
      </div>
      <div style="height: 100%; width: 1%"></div>
      <!-- 右侧聊天区域 -->
      <div class="ai-chat" :style="getBackgroundStyle(aiChatDetail)">
        <div class="ai-chat-title">
          <el-icon size="18" style="margin-right: 5px">
            <Service />
          </el-icon>
          数字人小森
        </div>
        <div class="ai-chat-detailnull" v-if="visible"></div>
        <div class="ai-chat-detail" ref="messageContainer">
          <div class="ai-chat-detail-avatar" v-for="(item, index) in msgList" :key="index">
            <div class="ai-chat-detail-avatar-item" v-if="item.type == 1">
              <div class="ai-chat-detail-avatar-item-img">
                <el-image :src="userInfo.avatar"></el-image>
              </div>

              <div class="ai-chat-detail-avatar-item-content">
                <p>{{ item.content }}</p>
              </div>
            </div>
            <div class="ai-chat-detail-avatar-item" v-if="item.type == 2">
              <div class="ai-chat-detail-avatar-item-img">
                <el-image :src="userInfo.avatar"></el-image>
              </div>

              <div class="ai-chat-detail-avatar-item-content">
                <img :src="item.play ? voiceIng : voiceplay" alt="" @click="recPlay(item.content, index)" />
                {{ formatSeconds(item.durationTime) }}
              </div>
            </div>
          </div>
        </div>
        <!-- <div class="overlay" v-if="isRecording">


          <img data-v-6b58f1ca="" crossorigin="anonymous" class="backImg" src="../../assets/icons/setrecording.png"
               alt="" @click="recStop" />
        </div> -->

        <div class="ai-chat-operator">
          <div class="ai-chat-operator-icon">
            <!-- <el-icon :size="20" @click="recStart">
              <Mic />
            </el-icon> -->

            <el-popover :visible="visible" placement="top-start" :width="335" trigger="click" :hide-after="0">
              <div class="overlay">
                <img data-v-6b58f1ca="" crossorigin="anonymous" :src="recType == 1
      ? Recordingimg
      : recType == 2
        ? RecordingOverimg
        : recType == 3
          ? Recordingplayimg
          : RecordingplayOverimg
      " alt="" />
              </div>

              <div class="voiceBtn">
                <el-button v-if="!recBlob" size="small" @click="recStop">结束</el-button>
                <el-button v-if="!recBlob" size="small" @click="endrec">取消</el-button>
                <el-button v-if="recBlob" size="small" @click="recStart">重录</el-button>
                <el-button v-if="recBlob" size="small" @click="recingplay">试听</el-button>
                <el-button v-if="recBlob" size="small" @click="sendVoice">发送</el-button>
                <el-button v-if="recBlob" size="small" @click="endrec">取消</el-button>
              </div>

              <template #reference>
                <img :src="visible ? voiceingimg : voiceimg" alt="" @click="recStarting" />
              </template>
            </el-popover>
          </div>
          <el-input :disabled="visible" v-model="msg" placeholder="请输入内容" class="ai-chat-detail-operator-input"
                    @keyup.enter="sendMsg" style="width: 260px; margin: 0px 5px" clearable></el-input>
          <div class="ai-chat-operator-icon">
            <!-- <el-icon :size="20"  @click="sendMsg">
              <Promotion />
            </el-icon> -->
            <img :src="sending" alt="" @click="sendMsg" />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
// 图片素材引入
import chatRoombgk from "@/assets/chatRoom/背景.png";
import aiAvatar from "@/assets/chatRoom/数字人.png";
import aiChatDetail from "@/assets/chatRoom/聊天背景.png";
import voiceimg from "@/assets/chatRoom/语音.png";
import voiceingimg from "@/assets/chatRoom/正在语音.png";
import sending from "@/assets/chatRoom/发送.png";
import voiceplay from "@/assets/chatRoom/语音效果.png";
import videoBgUrl from "@/assets/mp4/07_05.mp4";
import aiimg from "@/assets/chatRoom/aiimg.jpg";
// import videoBgSrc from "@/assets/mp4/07_05.mp4";
import Recordingimg from "@/assets/chatRoom/正在录制.png";
import RecordingOverimg from "@/assets/chatRoom/录制完成.png";
import Recordingplayimg from "@/assets/chatRoom/正在播放.png";
import RecordingplayOverimg from "@/assets/chatRoom/播放完成.png";
import voiceIng from "@/assets/chatRoom/voiceIng.gif";
// import RecordingplayOverimg from "@/assets/chatRoom/播放完成.png";
// ws://192.168.3.22:7788/digital-human/websocket/2
import { upload, uploadFile } from "@/api/upload";
import { getToken } from "@/utils/auth";
import { ElMessage } from "element-plus";
import useUserStore from "@/store/modules/user";
import { nextTick, onMounted } from "vue";
import websocketStore from "@/store/modules/websocketStore";
import { sendMessage } from "@/api/creation/websocket";
//必须引入的核心
import Recorder from "recorder-core";

//引入mp3格式支持文件；如果需要多个格式支持，把这些格式的编码引擎js文件放到后面统统引入进来即可
import "recorder-core/src/engine/mp3";
import "recorder-core/src/engine/mp3-engine";
//录制wav格式的用这一句就行
import "recorder-core/src/engine/wav";

//可选的插件支持项，这个是波形可视化插件
import "recorder-core/src/extensions/waveview";
const visible = ref(false);
const recing = ref(false);
const voiceNumber = ref(null);
const recType = ref(1);
const uploadHeaders = { Authorization: "Bearer " + getToken() };
const action = upload;
const durationTime = ref(null);
const msgList = ref([]);
const msg = ref("");
const rec = ref(null);
const wave = ref(null);
const recwave = ref(null);
const recBlob = ref(null);
const userInfo = useUserStore();
const wsStore = websocketStore();
const messageContainer = ref(null);
const audioUrl = ref("");
const imgElement = ref("");
const audiocishu = ref(0);
const videoElement = ref(null);
var dinshi = null
const videoBgSrc =
  // autoplay
  ref(`<video autoplay object-fit="fill" loop muted style="width: 100%;height: 640px;aspect-ratio: full;" crossorigin="anonymous" width="100%" >
<source src="${videoBgUrl}" type="video/mp4">
</video>`);
// 是否正在录音
const isRecording = ref(false);

const sendMsg = () => {
  if (visible.value) {
    return;
  }
  //   wsStore.sendMsg(msg.value);
  if (msg.value != "") {
    msgList.value.push({ content: msg.value, type: 1 });
    nextTick(() => {
      messageContainer.value.scrollTop = messageContainer.value.scrollHeight;
    });

    sendMessage({ content: msg.value })
      .then((res) => {

        // setTimeout(() => {
        //   dinshi = setInterval(() => {
        //     displayImage();
        //   }, 40);
        // }, 4000);
      })
      .catch((err) => {
        // 异常情况
        "发送失败", err;
      });
    msg.value = "";
  } else {
    ElMessage({
      message: "请输入内容",
      type: "warning",
    });
  }
};


// 不同权益不同背景
function getBackgroundStyle(imageUrl) {
  return {
    "background-image": `url(${imageUrl})`,
    "background-size": "cover",
    "background-repeat": "no-repeat",
    borderRadius: "10px",
  };
}
async function recOpen() {
  try {
    await navigator.mediaDevices.getUserMedia({ audio: true });
    console.log("录音权限已打开");
    rec.value = Recorder({
      type: "wav",
      sampleRate: 16000,
      bitRate: 16,
      onProcess: (buffers, powerLevel, bufferDuration, bufferSampleRate) => {
        if (wave.value) {
          wave.value.input(
            buffers[buffers.length - 1],
            powerLevel,
            bufferSampleRate
          );
        }
      },
    });

    if (recwave.value) {
      wave.value = Recorder.WaveView({ elem: recwave.value });
    }

    rec.value.open(
      () => {
        console.log("录音已打开");
      },
      (msg, isUserNotAllow) => {
        console.log(
          (isUserNotAllow ? "UserNotAllow，" : "") + "无法录音:" + msg
        );
      }
    );
  } catch (err) {
    console.error("无法打开录音权限:", err);
  }
}
const ONRec = () => {
  console.log("数字人语音结束,时间为：", Date.now());

  audioAi.value.src = "";
  clearInterval(dinshi);
  audiocishu.value = 1;
  imgElement.value = '';
  wsStore.cleanAudioAndImg(false);
  // videoElement.value.currentTime = 0;
  // audioAi.value.play()
};
const cleanRec = () => {
  recType.value = 4;
  recing.value = false;
  audio.value.pause();
  audio.value.src = "";
  msgList.value.forEach((item, index) => {
    msgList.value[index].play = false;
  });
};
// 播放
const recingplay = () => {
  recPlay(recBlob.value);
};

function recStarting() {
  if (visible.value == true) {
    return;
  }
  visible.value = true;
  recStart();
}
// 开始录音
function recStart() {
  if (audio.value) {
    audio.value.src = "";
  }

  msgList.value.forEach((item, index) => {
    msgList.value[index].play = false;
  });
  recType.value = 1;

  recBlob.value = null;
  if (!rec.value) {
    console.error("未打开录音");
    return;
  }

  rec.value.start();
  isRecording.value = true;
}
// 结束录音
function recStop() {
  recType.value = 2;
  if (!rec.value) {
    console.error("未打开录音");
    return;
  }

  rec.value.stop(
    (blob, duration) => {
      recBlob.value = blob;
      const localUrl = (window.URL || window.webkitURL).createObjectURL(blob);
      durationTime.value = Number(duration);
      isRecording.value = false;
      rec.value = null;
      recOpen();
    },
    (err) => {
      rec.value.close();
      rec.value = null;
    }
  );
}
// 发送语音
const sendVoice = () => {
  uploadAudio(recBlob.value).then((res) => {
    msgList.value.push({
      content: recBlob.value,
      type: 2,
      durationTime: durationTime.value,
      play: false,
    });
    durationTime.value = null;

    endrec();
  });
};
// 取消录音
const endrec = () => {
  recBlob.value = null;
  visible.value = false;
  recOpen();
};
// 上传文件
const uploadAudio = async (blob) => {
  // blob

  const formData = new FormData();
  formData.append("file", blob, "recording.wav");

  try {
    const response = await sendMessage(formData, uploadHeaders);
    // console.log("Upload success:", response.data);
    // audioUrl.value = response.data.fileUrl;
  } catch (error) {
    // console.error("Upload error:", error);
  }
};

// 播放录音
function recPlay(data, index) {
  recType.value = 3;
  if (!data) {
    return;
  }
  msgList.value.forEach((item, index) => {
    msgList.value[index].play = false;
  });
  const localUrl = URL.createObjectURL(data);
  audio.value = document.getElementById("audio");
  if (recing.value) {
    audio.value.pause();
    audio.value.src = "";
  }

  audio.value.controls = true;
  // document.body.appendChild(audio.value);
  audio.value.src = localUrl;
  if (typeof index == "number") {
    voiceNumber.value = index;
    msgList.value[index].play = true;

  }
  audio.value.play();

  setTimeout(() => {
    URL.revokeObjectURL(audio.value.src);
  }, 5000);
}
function formatSeconds(data) {
  Math.floor(data / 1000);
  if (Math.floor(data / 1000) < 60) {
    return Math.floor(data / 1000) + "''";
  } else {
    return (
      Math.floor(data / 1000 / 60) +
      "''" +
      Math.floor((data / 1000) % 60) +
      "''"
    );
  }
}
function displayImage() {
  console.log(wsStore.ws.imageQueue.length, "wsStore.ws.imageQueue.length")
  // if (wsStore.ws.imageQueue.length > 1) {
  const imageUrl = wsStore.ws.imageQueue.shift();
  imgElement.value = imageUrl;
  // }
  // else if (wsStore.ws.imageQueue.length == 1) {
  //   // wsStore.ws.imageQueue.shift();
  //   imgElement.value = "";
  //   console.log("1111111")
  //   // console.log(imgElement.value, "imgElement.value")
  //   // console.log(wsStore.ws.imageQueue, "wsStore");
  // }
}
const videoBghtml = computed(() => {
  return `<video  autoplay object-fit="fill" loop muted style="width: 100%;height: 100vh;aspect-ratio: full;" controls width="100%" height="600px"><source src="${videoBgSrc.value}" type="video/mp4"></video>`;
});

onMounted(() => {
  wsStore.init();
  recOpen();
  videoElement.value = document.querySelector("video");
  audioAi.value = document.getElementById("audioAi");
  // if (videoElement) {
  //       videoElement.play();
  //     }
});
// watch(
//   () => wsStore.chatMsg,
//   (newVal, oldVal) => {
//     console.log(newVal);
//     // msgList.value.push(newVal)
//   },
//   () => wsStore.buffer,
//   (newVal, oldVal) => {
//     console.log(newVal, "serviceMsg.value");
//     // msgList.value.push(newVal)
//   },
//   () => wsStore.serviceMsg,
//   (newVal, oldVal) => {
//     console.log(newVal, "serviceMsg.value");
//     // msgList.value.push(newVal)
//   }

// );
const subscribe = wsStore.$subscribe(
  (mutation, state) => {

    if (wsStore.audioGo && wsStore.imgGo) {
      wsStore.cleanAudioAndImg(false);
      // setTimeout(() => {


      audioAi.value.src = wsStore.ws.audioUrl;
      // const time = Math.floor((wsStore.duration * 1000) / wsStore.ws.imageQueue.length)
      // 图片播放


      // 启动音频和视频的播放
      if (videoElement.value) {
        videoElement.value.currentTime = 0;
      }
      audioAi.value.play();

      console.log("声音播放时间为：", Date.now()),
        videoElement.value.play();
      // setTimeout(() => {
      // Promise.all([


      //   videoElement.value ?  : Promise.resolve()
      // ]).catch(error => {
      //   console.error('播放音频或视频时出错:', error);
      // });
      // }, Math.floor((wsStore.duration * 1000) / wsStore.ws.imageQueue.length))



      // 
      // }, wsStore.duration * 1000);
      // 
      //  调用play
    }

    imgElement.value = wsStore.ws.imageQueue
  },
  { detached: false }
);

onBeforeUnmount(() => {
  if (wsStore) {
    wsStore.close({ isActiveClose: true });
  }
});

</script>

<style lang="scss" scoped>
// 边框颜色
$chat-border-color: 1px solid #cccccc69;
// 圆角
$chat-border-radius: 10px;

.chat-container {
  // border: 1px solid red;
  width: 100%;
  height: 800px;
  display: flex;
  align-items: center;
  justify-content: center;

  &-content {
    width: 1100px;
    height: 700px;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 30px;
    /* 背景图片居中 */
    // border: 1px solid red;
  }
}

.ai-avatar {
  width: 65%;
  height: 100%;
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;

  &-box {
    position: absolute;
    width: 308px;
    height: 640px;
    // border: 1px solid red;

    img {
      position: absolute;
      top: 8.8px;
      left: 75.85px;
      border-radius: $chat-border-radius;
      // width: 30px;
      height: 151.7px;
    }
  }

}

.ai-chat {
  width: 34%;
  height: 100%;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  position: relative;

  &-title {
    width: 100%;
    height: 50px;
    display: flex;

    align-items: center;
    // border: 1px solid red;
    font-weight: bold !important;
    // text-align: center;
    padding: 0px 10px;
    border-bottom: $chat-border-color;
  }

  &-detailnull {
    top: 50px;
    position: absolute;
    z-index: 999;
    height: calc(100% - 100px);
    width: 100%;
    background: #321eeb;
    filter: blur(5px);
    opacity: 0.09;
    // transition: all 1s;

    // transform: scale(1.1);
  }

  &-detail {
    height: calc(100% - 100px);
    padding: 5px;
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    justify-content: flex-start;
    overflow: auto;
    scrollbar-width: none;
    /* Firefox */
    -ms-overflow-style: none;

    /* IE and Edge */
    &-avatar {
      width: 100%;
      display: flex;
      // align-items: center;
      justify-content: flex-end;
      position: relative;
      // border: 1px solid red;
      margin-bottom: 10px;

      &-item {
        display: flex;
        flex-direction: row-reverse;
        // align-items: flex-end;
        // justify-content: flex-start;
        position: relative;
        min-height: 40px;

        &-img {
          position: absolute;
          right: 0px;
          top: 0px;
          max-width: 40px;
          max-height: 40px;
          padding: 0;
          border-radius: 40px;
          overflow: hidden;

          image {
            max-width: 40px;
            max-height: 40px;
          }
        }

        &-content {
          margin-right: 50px;
          max-width: 250px;
          border: $chat-border-color;
          // margin-top: 10px;
          background: white;
          border-radius: 8px;
          word-break: break-all;
          /*支持IE，chrome，FF不支持*/
          word-wrap: break-word;

          /*支持IE，chrome，FF*/
          p {
            padding: 5px;
            line-height: 30px;
          }

          img {
            // margin: 10px;
            height: 40px;
          }
        }
      }
    }
  }

  &-operator {
    padding: 5px;
    border-top: $chat-border-color;
    width: 100%;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 50px;

    &-icon {
      width: 40px;
      height: 50px;
      display: flex;
      justify-content: center;
      align-items: center;
      border-radius: 15px;

      img {
        cursor: pointer;
        width: 80%;
        border-radius: 15px;
        // height: 100%;
      }

      img:hover {
        border: $chat-border-color;
      }
    }
  }
}

::v-deep(.el-input__wrapper) {
  /*覆盖原背景颜色，设置成透明 */
  border-radius: 15px;
  // border: 0;
  box-shadow: 0 0 0 0px;
  border: 1px solid #837ada;
}

.overlay {
  position: relative;
  top: 0;
  left: 0;
  width: 100%;
  height: 50px;
  // background: rgba(0, 0, 0, 0.5);
  transition: opacity 0.5s ease;
  opacity: 1;
  display: flex;
  justify-content: center;

  img {
    height: 40px;
    // width: 100px;
  }
}

.voiceBtn {
  width: 100%;

  display: flex;
  justify-content: center;
}
</style>
